Skip to content

[中文版本](/posts/c教程/zh-CN/05-输入输出与文件/048-Reading Configuration Files)

As your C programs grow, hardcoding settings like file paths, thresholds, or user preferences becomes limiting. Configuration files let your program read settings at runtime, a critical capability for tools, servers, and embedded systems.

You’ll learn how to read and parse configuration files using standard I/O and string handling.

The Goal ​

A configuration file might look like this:

port=8080
host=localhost
max_clients=100
log_file=server.log

Your program should:

  1. Open the file
  2. Read it line by line
  3. Split each line intokey andvalue
  4. Store or use those values

Step 1. Define a Structure for Config ​

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LINE 128
typedef struct {
    int port;
    char host[64];
    int max_clients;
    char log_file[64];
} Config;

ThisConfig struct will hold parsed values.

Step 2. Implement the Parser ​

void load_config(const char *filename, Config *cfg) {
    FILE *fp = fopen(filename, "r");
    if (!fp) {
        perror("Cannot open config file");
        exit(1);
    }
    char line[MAX_LINE];
    while (fgets(line, sizeof(line), fp)) {
        line[strcspn(line, "\n")] = '\0'; // remove newline
        if (line[0] == '#' || strlen(line) == 0)
            continue; // skip comments and blanks
        char key[64], value[64];
        if (sscanf(line, "%63[^=]=%63s", key, value) == 2) {
            if (strcmp(key, "port") == 0)
                cfg->port = atoi(value);
            else if (strcmp(key, "host") == 0)
                strncpy(cfg->host, value, sizeof(cfg->host));
            else if (strcmp(key, "max_clients") == 0)
                cfg->max_clients = atoi(value);
            else if (strcmp(key, "log_file") == 0)
                strncpy(cfg->log_file, value, sizeof(cfg->log_file));
        }
    }
    fclose(fp);
}

This function:

  • Reads each line
  • Ignores comments and empty lines
  • Extracts key-value pairs usingsscanf()
  • Updates fields inConfig

Step 3. Use the Configuration ​

int main(void) {
    Config cfg = {0};
    load_config("config.txt", &cfg);
    printf("Server settings:\n");
    printf("Host: %s\n", cfg.host);
    printf("Port: %d\n", cfg.port);
    printf("Max clients: %d\n", cfg.max_clients);
    printf("Log file: %s\n", cfg.log_file);
    return 0;
}

Run with aconfig.txt file:

host=127.0.0.1
port=9090
max_clients=250
log_file=/tmp/server.log

Output:

Server settings:
Host: 127.0.0.1
Port: 9090
Max clients: 250
Log file: /tmp/server.log

Tiny Code: Default Fallbacks ​

You can initialize sensible defaults before reading the file:

Config cfg = {
    .port = 8080,
    .host = "localhost",
    .max_clients = 100,
    .log_file = "server.log"
};

This ensures your program still works even if the file is missing some values.

Step 4. Optional: Handle Quoted Values ​

If you expect values with spaces (likename="My Server"), you can modify parsing logic:

if (sscanf(line, "%63[^=]=\"%63[^\"]\"", key, value) == 2) {
    // handle quoted strings
}

Step 5. Optional: Generic Storage ​

For more flexible systems, you can use a hash table or array of key-value pairs instead of fixed fields:

typedef struct {
    char key[64];
    char value[64];
} KVPair;
KVPair settings[100];

This allows loading arbitrary keys without recompiling the program.

Why It Matters ​

Configuration files let you:

  • Separate code from data, no need to recompile to change behavior
  • Adapt to environments, dev, test, production
  • Make your program reusable by others

They’re used everywhere, from.ini and.conf files to complex YAML/JSON formats in modern systems.

Try It Yourself ​

  1. Add support for# comments and empty lines (skip them safely).
  2. Make the parser print a warning for unknown keys.
  3. Add a functionsave_config() that writes the struct back to a file.
  4. Addreload_config() to update settings at runtime.
  5. Implement your own.ini format parser supporting[section] headers.

With configuration files, your C programs gain flexibility and real-world usability, they can adapt, reload, and persist settings just like professional systems software. Next, you’ll learn how to serialize and deserialize structs to disk, the next level of persistent data handling in Section 49.

本站总访问 — 次